# -*- coding: utf-8 -*-

__author__ = 'bilibili'

import types
import copy
import abc
from spot_excel_reader import spot_excel_reader
from spot_config import spot_config

class spot_excel_analyzer_base:
    @abc.abstractmethod
    def fetch_key(self, in_dict):
        return 'key'

    @abc.abstractmethod
    def new_value(self, in_dict):
        return None

    @abc.abstractmethod
    def value_operation(self, key, in_dict):
        pass

    @abc.abstractmethod
    def post_build_operation(self):
        pass

    @abc.abstractmethod
    def customized_calculation(self, arg_list):
        pass

    # FUNCTION: __init__(self, string)
    #   the constructor of the class spot_excel_analyzer_base
    # ARGS:
    #   @config_name: json config file name
    def __init__(self, config_name):
        self.config = spot_config(config_name)
        self.excel = spot_excel_reader(self.config.get_attr('config', 'excel_file_name'), self.config.get_attr('config', 'excel_sheet_name'))
        self.attr_1 = self.config.get_attr('config', 'attr_row_1')
        self.attr_2 = self.config.get_attr('config', 'attr_row_2')
        if self.attr_2 == None:
            del(self.attr_2)
        self.column_base = self.config.get_attr('config', 'column_base')

    # FUNCTION: build_entry(self, int, int)
    #   to convert one row in the excel into a dictionary
    # ARGS:
    #   @row_num: the row number to needs to be converted
    #   @column_base: the base column number for the offset
    # RETURN:
    #   dict: the dictionary that is converted from one line of the excel
    def build_entry(self, row_num, column_base):
        tmp_dict = copy.deepcopy(self.config.get_dict())
        del(tmp_dict['config'])
        for (d, x) in self.config.get_dict().items():
            if d == 'config':
                continue
            if type(x) == types.IntType:
                tmp_dict[d] = self.excel.get_cube(row_num, x + column_base)
            else: # it's a dictionary
                for (d2, x2) in x.items():
                    tmp_dict[d][d2] = self.excel.get_cube(row_num, x2 + column_base)
        return tmp_dict

    # FUNCTION: build_whole_table(self)
    #   to convert the whole table into dictionaries
    #   calling all the virtual functions
    def build_whole_table(self):
        self.res_dict = {}
        for i in range(self.attr_1 + 1, self.excel.get_row_count()):
            tmp_dict = self.build_entry(i, self.column_base)
            key = self.fetch_key(tmp_dict)
            if not self.res_dict.has_key(key):
                self.res_dict[key] = self.new_value(tmp_dict)
            self.value_operation(key, tmp_dict)
        self.post_build_operation()

    # FUNCTION: get_result_dict(self)
    #   get the raw dictionary
    def get_result_dict(self):
        return self.res_dict

    # FUNCTION: get_level_1_info(self, string)
    #   get the raw dictionary
    # ARGS:
    #   @key_1: first key
    # RETURN:
    #   dict: the dictionary to the key_1
    def get_level_1_info(self, key_1):
        return self.res_dict[key_1]

    # FUNCTION: get_level_2_info(self, string, string)
    #   get the raw dictionary
    # ARGS:
    #   @key_1: first key
    #   &key_2: second key
    # RETURN:
    #   string: the dictionary to the key_1 and key_2
    def get_level_2_info(self, key_1, key_2):
        return self.res_dict[key_1][key_2]
